package com.common.www.config;

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;

import javax.net.ssl.SSLContext;

/**
 * @program: wmp
 * @description:
 * @author: Chenjiabin
 * @create: 2018-04-22 20:29
 **/
@Configuration
public class RestTemplateConfiguration {

    @Bean("simpleRestTemplate")
    public RestTemplate restTemplate(@Qualifier("simpleClientHttpRequestFactory") ClientHttpRequestFactory factory) {
//        RestTemplate restTemplate = new RestTemplate(factory);
        return getInstance("utf-8", factory);
    }

    public static RestTemplate getInstance(String charset, ClientHttpRequestFactory requestFactory) {
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        List<HttpMessageConverter<?>> list = restTemplate.getMessageConverters();
        for (HttpMessageConverter<?> httpMessageConverter : list) {
            if (httpMessageConverter instanceof StringHttpMessageConverter) {
                ((StringHttpMessageConverter) httpMessageConverter).setDefaultCharset(Charset.forName(charset));
                break;
            }
        }
        return restTemplate;
    }

    @Bean("simpleClientHttpRequestFactory")
    public HttpComponentsClientHttpRequestFactory simpleClientHttpRequestFactory() {

        HttpClientBuilder builder = HttpClientBuilder.create().setDefaultCookieStore(new BasicCookieStore())
                .setRedirectStrategy(new LaxRedirectStrategy());
        final HttpClient httpClient = builder.build();

        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setReadTimeout(120 * 1000);
        factory.setHttpClient(httpClient);
        return factory;
    }

//    @Bean("sslRestTemplate")
//    public RestTemplate sslRestTemplate(@Qualifier("sslClientHttpRequestFactory") ClientHttpRequestFactory factory) {
//        return new RestTemplate(factory);
//    }

    @Bean("sslClientHttpRequestFactory")
    public HttpComponentsClientHttpRequestFactory sslClientHttpRequestFactory() {
        TrustStrategy trustStrategy = new TrustStrategy() {
            public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                return true;
            }
        };
        SSLContext sslContext = null;
        try {
            sslContext = new SSLContextBuilder().loadTrustMaterial(null, trustStrategy).build();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        HttpClientBuilder builder = HttpClientBuilder.create().setDefaultCookieStore(new BasicCookieStore())
                .setRedirectStrategy(new LaxRedirectStrategy()).setSSLContext(sslContext);
        final HttpClient httpClient = builder.build();
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setReadTimeout(120 * 1000);
        factory.setHttpClient(httpClient);
        return factory;
    }
}